package com.magold.skill.cast;

import org.andengine.entity.scene.Scene;
import org.andengine.extension.physics.box2d.PhysicsWorld;

import com.magold.algorithm.Line2D;
import com.magold.physics.magnetic.Monopole;
import com.magold.touch.ISwipeDetector;
import com.magold.touch.ISwipeDetector.ISwipeListener;

public class CastSkillTouchListener implements ISwipeListener {
	private final AttacherManager mAttacherManager;
	private final PhysicsWorld mWorld;
	private final Monopole mUser;
	private boolean mDrawingArc;
	private boolean mStopped;
	private final float mTriggerDistance;
	
	public CastSkillTouchListener(PhysicsWorld pWorld, AttacherManager pAttacherManager, float pTriggerDistance, Monopole pUser) {
		 mAttacherManager = pAttacherManager;
		 mWorld = pWorld;
		 mDrawingArc = false;
		 mTriggerDistance = Math.abs(pTriggerDistance);
		 mUser = pUser;
	}

	@Override
	public void onSwipeStarted(Scene pScene, ISwipeDetector pDetector) {
		mStopped = false;
	}
	
	@Override
	public void onSwipe(Scene pScene, ISwipeDetector pDetector) {
		if (mStopped) return;
		
		boolean usingSkill = mAttacherManager.isUsingCastSkill();
		
		if (!usingSkill) { // start use skill.
			float delta = pDetector.getCurrentY() - pDetector.getStartY();
			boolean shouldStart = Math.abs(delta) > mTriggerDistance;
			
			if (shouldStart) {
				mAttacherManager.startCastSkill(mWorld, delta > 0.0f, mUser.getPole());
				mDrawingArc = true;
			}
		} else if (!mDrawingArc && isCutted(pDetector)) {
			stop();	// stop use skill.
		}
	}

	@Override
	public void onSwipeFinished(Scene pScene, ISwipeDetector pDetector, boolean pMultitouchOccured) {
		if (mStopped || !mAttacherManager.isUsingCastSkill()) return;
		
		if (mDrawingArc) {
			mDrawingArc = false;
		} else if (isCutted(pDetector)) {
			stop();
		}
	}

	/**
	 * stop use skill and do nothing in this interactive.
	 */
	private void stop() {
		mStopped = true;
		mAttacherManager.stopCastSkill();
	}

	private final Line2D.Float mCuttingLineBuf = new Line2D.Float();
	private boolean isCutted(ISwipeDetector pDetector) {
		Line2D.Float magneticLine = mAttacherManager.getMagneticLine();
		
		// illegal state.
		if (magneticLine == null) return false;
		
		float x1 = pDetector.getStartX(), y1 = pDetector.getStartY();
		float x2 = pDetector.getCurrentX(), y2 = pDetector.getCurrentY();
		mCuttingLineBuf.setLine(x1, y1, x2, y2);
		
		return mCuttingLineBuf.intersectsLine(magneticLine);
	}

}
